#include "EditorDebugConsoleModel.h"

#include "Language/EditorScriptDebugSubsystem.h"
#include "Framework/Editor.h"

void REditorDebugConsoleModel::FirstTimeInitializeObject()
{
    Super::FirstTimeInitializeObject();
    Lines.Reserve(InitialMemorySize);

    REditor::Get()->GetSubsystem<REditorScriptDebugSubsystem>()
        ->OnProjectPrint.BindScript(this,&REditorDebugConsoleModel::OnPrint);
    
    REditor::Get()->GetSubsystem<REditorScriptDebugSubsystem>()->OnDebugStarted
        .BindScript(this,&REditorDebugConsoleModel::OnDebugSessionStarted);
}

void REditorDebugConsoleModel::PostLoadFromAsset()
{
    Super::PostLoadFromAsset();
    if(Lines.Capacity()<InitialMemorySize)
    {
        Lines.Reserve(InitialMemorySize);
    }
}

void REditorDebugConsoleModel::AddLine(const CString &InLineContent, EDebugConsoleLineType InLineType )
{
    if((Lines.Num()+1)>=Lines.Capacity())
    {
        Lines.Reserve(Lines.Capacity()+InitialMemorySize);
    }
    SDebugConsoleLine InLine;
    InLine.Content = InLineContent;
    InLine.LineType = InLineType;
    Lines.Add(InLine);
    OnLineNumChanged.ExecuteIfBound();    
}

void REditorDebugConsoleModel::ClearLines()
{
    Lines.Clear(false);
    OnLineNumChanged.ExecuteIfBound();
}

void REditorDebugConsoleModel::OnPrint(const CString &InNewMessage)
{
    CString NewMessage = InNewMessage;
    int64_t EndIndex=-1;
    do{
        EndIndex=NewMessage.Find(U'\n');
        if(EndIndex!=-1)
        {
            AddLine(NewMessage.Left(EndIndex+1));
            NewMessage=NewMessage.Right(NewMessage.GetLength()-EndIndex-1);
        }
    }
    while(EndIndex!=-1);

    if(!NewMessage.IsEmpty())
    {
        AddLine(NewMessage);
    }
}

void REditorDebugConsoleModel::OnDebugSessionStarted()
{
    ClearLines();
}
